package com.skzh.uavTask.task;

import com.skzh.common.utils.DateUtils;
import com.skzh.uavTask.domain.TaskInfo;
import com.skzh.uavTask.domain.TaskExecRecord;
import com.skzh.uavTask.service.ITaskInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.JsonNode;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.TimeZone;

/**
 * 任务状态检查定时任务
 */
@Component("ryTask2")
public class TaskStatusChecker {
    private static final Logger log = LoggerFactory.getLogger(TaskStatusChecker.class);

    private static final String SYSTEM_USER = "system";  // 系统用户

    @Autowired
    private ITaskInfoService taskService;

    public void checkTaskStatus() {
        try {
            // 查询所有待执行的定时和周期任务
            TaskInfo queryTask = new TaskInfo();
            queryTask.setStatus("0"); // 待执行状态
            List<TaskInfo> tasks = taskService.selectTaskList(queryTask);
            log.debug("开始检查任务状态，共有{}个待执行任务", tasks.size());

            tasks.forEach(task -> {
                try {
                    if ("1".equals(task.getExecType())) {
                        // 定时执行任务
                        checkScheduledTask(task);
                    } else if ("2".equals(task.getExecType())) {
                        // 周期执行任务
                        checkCyclicTask(task);
                    }
                } catch (Exception e) {
                    log.error("检查任务[{}]状态时发生错误：{}", task.getTaskId(), e.getMessage());
                }
            });
        } catch (Exception e) {
            log.error("检查任务状态时发生错误", e);
        }
    }

    /**
     * 检查定时执行任务
     */
    private void checkScheduledTask(TaskInfo task) {
        try {
            JsonNode execTimes = task.getExecTime();
            if (execTimes != null && execTimes.isArray()) {
                Date now = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                for (JsonNode timeNode : execTimes) {
                    String timeStr = timeNode.asText()
                        .replace("T", " ")
                        .replace(".000Z", "")
                        .replace("Z", "");
                    // 处理时区问题，将UTC时间转换为本地时间
                    Date execTime = new Date(sdf.parse(timeStr).getTime() + 8 * 60 * 60 * 1000);

                    // 计算时间差（分钟）
                    long diffMinutes = Math.abs((now.getTime() - execTime.getTime()) / (60 * 1000));

                    // 如果在1分钟范围内，且没有执行记录，则启动任务
                    if (diffMinutes <= 1 && !hasExecRecord(task.getTaskId(), execTime)) {
                        log.info("定时任务[{}]开始执行，计划执行时间：{}，当前时间：{}",
                            task.getTaskName(), sdf.format(execTime), sdf.format(now));
                        boolean shouldStartTask = true;
                        if (shouldStartTask) {
                            log.debug("开始执行定时任务，任务ID：{}，执行时间：{}", task.getTaskId(), execTime);
                            taskService.startTask(task.getTaskId(), SYSTEM_USER);
                        }
                        break;
                    }
                }
            }
        } catch (Exception e) {
            log.error("检查定时任务状态时发生错误，任务ID：{}，错误：{}", task.getTaskId(), e.getMessage());
        }
    }

    /**
     * 检查周期执行任务
     */
    private void checkCyclicTask(TaskInfo task) {
        try {
            JsonNode cycleTimes = task.getCycleTime();
            if (cycleTimes != null && cycleTimes.isArray()) {
                Date now = new Date();
                Calendar cal = Calendar.getInstance();
                SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
                String currentTime = timeFormat.format(now);

                log.debug("检查周期任务[{}]，当前时间：{}", task.getTaskName(), currentTime);

                for (JsonNode timeNode : cycleTimes) {
                    String cycleTime = timeNode.asText();
                    // 如果是ISO格式的时间戳，转换为HH:mm格式
                    if (cycleTime.contains("T")) {
                        try {
                            SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                            isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
                            Date date = isoFormat.parse(cycleTime);
                            // 转换为本地时间
                            Calendar localCal = Calendar.getInstance();
                            localCal.setTime(date);
                            localCal.add(Calendar.HOUR_OF_DAY, 8); // 转换为北京时间
                            cycleTime = timeFormat.format(localCal.getTime());
                        } catch (Exception e) {
                            log.error("解析ISO时间格式失败：{}", cycleTime, e);
                            continue;
                        }
                    }

                    log.debug("周期任务[{}]的执行时间：{}", task.getTaskName(), cycleTime);

                    // 检查是否到达执行时间（允许1分钟的误差）
                    if (isTimeWithinRange(currentTime, cycleTime, 1)) {
                        if (!hasExecRecordToday(task.getTaskId())) {
                            log.info("周期任务[{}]开始执行，执行时间：{}，当前时间：{}",
                                task.getTaskName(), cycleTime, currentTime);
                            startTaskWithRetry(task, cycleTime);
                            break;
                        } else {
                            log.debug("周期任务[{}]今天已经执行过", task.getTaskName());
                        }
                    } else {
                        log.debug("周期任务[{}]未到执行时间", task.getTaskName());
                    }
                }
            }
        } catch (Exception e) {
            log.error("检查周期任务状态时发生错误，任务ID：{}，错误：{}", task.getTaskId(), e.getMessage(), e);
        }
    }

    /**
     * 检查是否已经有指定时间的执行记录
     */
    private boolean hasExecRecord(Long taskId, Date execTime) {
        List<TaskExecRecord> records = taskService.selectTaskExecRecordList(taskId);
        if (records != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            String targetTime = sdf.format(execTime);

            for (TaskExecRecord record : records) {
                if (sdf.format(record.getExecTime()).equals(targetTime)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检查今天是否已经有执行记录
     */
    private boolean hasExecRecordToday(Long taskId) {
        List<TaskExecRecord> records = taskService.selectTaskExecRecordList(taskId);
        if (records != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String today = sdf.format(new Date());

            for (TaskExecRecord record : records) {
                if (record.getExecTime() != null && sdf.format(record.getExecTime()).equals(today)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检查时间是否在指定范围内
     */
    private boolean isTimeWithinRange(String currentTime, String targetTime, int minutesRange) {
        try {
            SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
            Date current = timeFormat.parse(currentTime);
            Date target = timeFormat.parse(targetTime);

            // 计算分钟差
            long diffMinutes = Math.abs((current.getTime() - target.getTime()) / (60 * 1000));

            // 处理跨天的情况
            if (diffMinutes > 720) { // 如果差异超过12小时，说明可能是跨天
                diffMinutes = 1440 - diffMinutes; // 1440是24小时的分钟数
            }

            log.debug("时间比较 - 当前时间：{}，目标时间：{}，差异分钟：{}", currentTime, targetTime, diffMinutes);

            return diffMinutes <= minutesRange;
        } catch (Exception e) {
            log.error("比较时间范围时发生错误：current={}, target={}", currentTime, targetTime, e);
            return false;
        }
    }

    /**
     * 尝试启动任务，如果失败则重试
     */
    private void startTaskWithRetry(TaskInfo task, String execTime) {
        int maxRetries = 3;
        int retryCount = 0;
        boolean success = false;

        while (!success && retryCount < maxRetries) {
            try {
                int result = taskService.startTask(task.getTaskId(), SYSTEM_USER);
                if (result > 0) {
                    log.info("任务[{}]启动成功，执行时间：{}", task.getTaskName(), execTime);
                    success = true;
                } else {
                    log.warn("任务[{}]启动失败，第{}次重试", task.getTaskName(), retryCount + 1);
                    retryCount++;
                    if (retryCount < maxRetries) {
                        Thread.sleep(1000); // 等待1秒后重试
                    }
                }
            } catch (Exception e) {
                log.error("任务[{}]启动异常，第{}次重试：{}", task.getTaskName(), retryCount + 1, e.getMessage());
                retryCount++;
                if (retryCount >= maxRetries) {
                    try {
                        taskService.failTask(task.getTaskId(), "任务启动失败，重试次数已达上限：" + e.getMessage());
                    } catch (Exception ex) {
                        log.error("更新任务失败状态时发生错误，任务ID：{}，错误：{}", task.getTaskId(), ex.getMessage());
                    }
                }
            }
        }
    }
}
